package org.kuaishou.httputil;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.apache.http.HttpEntity;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class HttpClientUtil implements IHttpRequest {

    private static final CloseableHttpClient HTTP_CLIENT = HttpClients.createDefault();

    @Override
    public ResponseResult send(RequestArgs requestArgs) throws Exception {
        ResponseResult responseResult = new ResponseResult();
        String httpMethod = requestArgs.getHttpMethod();
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        switch (httpMethod) {
            case "GET":
                responseResult = this.sendGet(requestArgs);
                break;
            case "POST":
                responseResult = this.sendPost(requestArgs);
                break;
            case "PUT":
                responseResult = this.sendPut(requestArgs);
                break;
            case "DELETE":
                responseResult = this.sendDelete(requestArgs);
                break;
            default:
                break;
        }
        stopWatch.stop();
        long watchTime = stopWatch.getTime(TimeUnit.MILLISECONDS);
        responseResult.setWatchTime(watchTime);
        return responseResult;
    }

    // 发送GET请求
    @Override
    public ResponseResult sendGet(RequestArgs requestArgs) throws IOException, URISyntaxException {
        String argsUrl = requestArgs.getUrl();
        Map<String, String> headerMap = requestArgs.getHeaderMap();
        Map<String, String> paramMap = requestArgs.getParameMap();

        URIBuilder uriBuilder = new URIBuilder(argsUrl);
        if (paramMap != null) {
            for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                if (StringUtils.isNotBlank(entry.getKey())) {
                    uriBuilder.addParameter(entry.getKey(), entry.getValue());
                }
            }
        }
        String sendUrl = uriBuilder.build().toString();

        HttpGet httpGet = new HttpGet(sendUrl);
        if (headerMap != null) {
            for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                if (StringUtils.isNotBlank(entry.getKey())) {
                    httpGet.addHeader(entry.getKey(), entry.getValue());
                }
            }
        }

        ResponseResult responseResult = new ResponseResult();
        responseResult.setRequestUrl(sendUrl);

        try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpGet)) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String string = EntityUtils.toString(entity);
                responseResult.setBody(string);
                StatusLine statusLine = response.getStatusLine();
                responseResult.setStatus(String.format("%s %s",statusLine.getStatusCode(),statusLine.getReasonPhrase()));
            }
        }

        return responseResult;
    }

    // 发送POST请求
    @Override
    public ResponseResult sendPost(RequestArgs requestArgs) throws Exception {
        String argsUrl = requestArgs.getUrl();
        Map<String, String> headerMap = requestArgs.getHeaderMap();
        Map<String, String> paramMap = requestArgs.getParameMap();
        String jsonBody = requestArgs.getJsonBody();

        URIBuilder uriBuilder = new URIBuilder(argsUrl);
        if (paramMap != null) {
            for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                if (StringUtils.isNotBlank(entry.getKey())) {
                    uriBuilder.addParameter(entry.getKey(), entry.getValue());
                }
            }
        }
        String sendUrl = uriBuilder.build().toString();

        HttpPost httpPost = new HttpPost(sendUrl);
        if (headerMap != null) {
            for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                if (StringUtils.isNotBlank(entry.getKey())) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
        }

        StringEntity entity = new StringEntity(jsonBody, "application/json", "UTF-8");
        httpPost.setEntity(entity);

        ResponseResult responseResult = new ResponseResult();
        responseResult.setRequestUrl(sendUrl);

        try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpPost)) {
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                String string = EntityUtils.toString(responseEntity);
                responseResult.setBody(string);
                StatusLine statusLine = response.getStatusLine();
                responseResult.setStatus(String.format("%s %s",statusLine.getStatusCode(),statusLine.getReasonPhrase()));
            }
        }

        return responseResult;
    }

    // 发送PUT请求
    @Override
    public ResponseResult sendPut(RequestArgs requestArgs) throws Exception {
        String argsUrl = requestArgs.getUrl();
        Map<String, String> headerMap = requestArgs.getHeaderMap();
        Map<String, String> paramMap = requestArgs.getParameMap();
        String jsonBody = requestArgs.getJsonBody();

        URIBuilder uriBuilder = new URIBuilder(argsUrl);
        if (paramMap != null) {
            for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                if (StringUtils.isNotBlank(entry.getKey())) {
                    uriBuilder.addParameter(entry.getKey(), entry.getValue());
                }
            }
        }
        String sendUrl = uriBuilder.build().toString();

        HttpPut httpPut = new HttpPut(sendUrl);
        if (headerMap != null) {
            for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                if (StringUtils.isNotBlank(entry.getKey())) {
                    httpPut.addHeader(entry.getKey(), entry.getValue());
                }
            }
        }

        StringEntity entity = new StringEntity(jsonBody, "application/json", "UTF-8");
        httpPut.setEntity(entity);

        ResponseResult responseResult = new ResponseResult();
        responseResult.setRequestUrl(sendUrl);

        try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpPut)) {
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                String string = EntityUtils.toString(responseEntity);
                responseResult.setBody(string);
                StatusLine statusLine = response.getStatusLine();
                responseResult.setStatus(String.format("%s %s",statusLine.getStatusCode(),statusLine.getReasonPhrase()));
            }
        }

        return responseResult;
    }

    // 发送DELETE请求
    @Override
    public ResponseResult sendDelete(RequestArgs requestArgs) throws Exception {
        String argsUrl = requestArgs.getUrl();
        Map<String, String> headerMap = requestArgs.getHeaderMap();
        Map<String, String> paramMap = requestArgs.getParameMap();
        String jsonBody = requestArgs.getJsonBody();

        URIBuilder uriBuilder = new URIBuilder(argsUrl);
        if (paramMap != null) {
            for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                if (StringUtils.isNotBlank(entry.getKey())) {
                    uriBuilder.addParameter(entry.getKey(), entry.getValue());
                }
            }
        }
        String sendUrl = uriBuilder.build().toString();

        HttpDelete httpDelete = new HttpDelete(sendUrl);
        if (headerMap != null) {
            for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                if (StringUtils.isNotBlank(entry.getKey())) {
                    httpDelete.addHeader(entry.getKey(), entry.getValue());
                }
            }
        }

        ResponseResult responseResult = new ResponseResult();
        responseResult.setRequestUrl(sendUrl);

        try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpDelete)) {
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                String string = EntityUtils.toString(responseEntity);
                responseResult.setBody(string);
                StatusLine statusLine = response.getStatusLine();
                responseResult.setStatus(String.format("%s %s",statusLine.getStatusCode(),statusLine.getReasonPhrase()));
            }
        }

        return responseResult;
    }
}
